iT邦幫忙

2024 iThome 鐵人賽

DAY 4
0
Python

在AWS上進行物聯網與人工智慧實作系列 第 4

D04-Python 基本資料類型

  • 分享至 

  • xImage
  •  

Python 基本資料類型

除了一般常見的數字、字串等比較簡單的資料類型,Python 中可以通過組合一些值,來得到多種複合資料類型。其中最常用的是列表 (list)、字典 (dictionary)、元組 (tuple)與集合(Set)。

列表介紹

列表 是 Python 中使用最頻繁的資料類型。

  • Python 的列表如同 Perl 中的陣列,在 Python 中,變數可以任意取名,並且 Python 在內部會記錄下其資料類型。
  • Python 的列表更像 Java 中的陣列,一個更好的類比是 ArrayList 類,它可以保存任意物件,並且可以在增加新元素時動態擴展。
  • 可以通過方括號括起、逗號分隔的一組值(元素)得到列表,一個列表可以包含不同類型的元素,但通常使用時各個元素類型相同。
  • 列表也支持索引切片
>>> list1 = [1, 4, 9, 16, "Hello"]
>>> list1
[1, 4, 9, 16, 'Hello']
>>> list1[0] 
1
>>> list1[-3:]
[9, 16, 'Hello']

賦值、淺拷貝與深拷貝

當我們把一個**物件賦值 (Assignment)**給一個新的變數時,賦與的其實是該物件的在記憶體中的地址,而不是陣列中的資料,也就是兩個物件指向的是同一個儲存空間,無論哪個物件發生改變,其實都是改變的儲存空間的內容,因此,兩個物件是連動的。深拷貝 (Deep copy)淺拷貝 (Shallow copy) 是只針對物件 (Object) 和陣列 (Array) 這樣的引用資料類型的。

  • 賦值 (Assignment) 給一個新的變數時,其實是該物件的在棧(heap)中的地址,而不是堆(stack)中的資料。
  • 淺拷貝(Shallow copy)會複製指向某個物件的指標,以及該物件第一層的所有數據,並形成一個新物件。
  • 深拷貝(Deep copy),新增一個一模一樣的物件,新物件跟原物件不共享記憶體。

淺拷貝只複製指向某個物件的指標,而不複製物件本身,新舊物件還是共享同一塊記憶體。但深拷貝會另外創造一個一模一樣的物件,新物件跟原物件不共享記憶體,修改新物件不會改到原物件。

https://ithelp.ithome.com.tw/upload/images/20240811/20129510IttbOLOM48.png
圖 1. 賦值、淺拷貝與深拷貝比較

因為列表就是一個陣列,讓我們來看一下這三個操作的差異。

>>> # 賦值範例,可以發現最後兩個變數的位址是一樣的
>>> list1 = [1, 4, 9, 16, [1,3,5]]
>>> assign1 = list1
>>> assign1[0] = 30
>>> assign1[4][1] = 10
>>> print(assign1," address = ",id(assign1))
[30, 4, 9, 16, [1, 10, 5]]  address =  2079473843328
>>> print(list1," address = ",id(list1))
[30, 4, 9, 16, [1, 10, 5]]  address =  2079473843328

以下為淺拷貝範例,淺拷貝會複製指向某個物件的指飆,以及該物件第一層的所有資料,並形成一個新物件,最後兩個變數的位址是不一樣的。所以,可以發現第一個值 1 在淺拷貝列表 shallow1 中有改變為 30 ,但原列表 list1 中沒有;但當改變列表中的列表 1,3,5 的中間那個值 3 -> 10 時,兩個列表顯示出來的結果都相同,因為嵌套列表的指標指向相同的位址。

>>> # 淺拷貝範例
>>> list1 = [1, 4, 9, 16, [1,3,5]]
>>> shallow1 = list1.copy()
>>> shallow1[0] = 30
>>> shallow1[4][1] = 10
>>> print(shallow1," address = ",id(shallow1))
[30, 4, 9, 16, [1, 10, 5]]  address =  2079473843392
>>> print(list1," address = ",id(list1))
[1, 4, 9, 16, [1, 10, 5]]  address =  2079473657728

以下為深拷貝範例,創造一個一模一樣的物件,新物件跟原物件不共享記憶體,最後兩個變數的位址是不一樣的。所以,可以發現所有的改變都不會影響到原列表。

>>> # 深拷貝範例
>>> import copy
>>> list1 = [1, 4, 9, 16, [1,3,5]]
>>> deep1 = copy.deepcopy(list1)
>>> deep1[0] = 30
>>> deep1[4][1] = 10
>>> print(deep1," address = ",id(deep1))
[30, 4, 9, 16, [1, 10, 5]]  address =  2079473658560
>>> print(list1," address = ",id(list1))
[1, 4, 9, 16, [1, 3, 5]]  address =  2079473843712
  
  指向原資料 第一層資料為基本資料類型 元資料中包含子物件
賦值 會同時改變 會同時改變
淺拷貝 不會同時改變 會同時改變
深拷貝 不會同時改變 不會同時改變
表 1. 賦值、淺拷貝與深拷貝比較表

根據 Python 官方說明,所有的切片操作都返回一個新列表,這個新列表包含所需要的元素,這個新列表是一個新的淺拷貝。此外根據剛才的操作,與不可修改 (immutable) 的字符串不同, 列表是一個 可修改 (mutable) 類型,就是說,它自己的內容可以改變。

>>> list1 = [1, 4, 9, 16, 25]
>>> list2 = list1[:] # 淺拷貝
>>> list3 = list1 # 賦值
>>> print(id(list1),id(list2), id(list3))
2079473658304 2079473657856 2079473658304
>>> list2[0] = 30

列表常用的操作

  • append(obj):來添加新元素。
  • extend(obj):擴展新元素。
  • remove(obj):移除列表中某個值的第一匹配項。
  • inset(index, obj):用於將指定物件插入列表的指定位置。
  • pop(index): 要移除列表中對下標對應的元素。
  • sort():對列表進行排序。
  • reverse():反向列表中元素。
>>> list1 = [1, 4, 9, 16, 25]
>>> list1.append([1,3,5])
>>> list1
[1, 4, 9, 16, 25, [1, 3, 5]]
>>> list1.extend([1,3,5]) # 會將陣列展開為一串數字
>>> list1
[1, 4, 9, 16, 25, [1, 3, 5], 1, 3, 5]
>>> list1.remove([1,3,5])
>>> list1
[1, 4, 9, 16, 25, 1, 3, 5]
>>> list1 = list1[:5]
>>> list1.insert(1,4)
>>> list1
[1, 4, 9, 16, 25, 36]
>>> list1.pop(1)
4
>>> list1
[1, 9, 16, 25, 36]
>>> list1.reverse()
>>> list1
[36, 25, 16, 9, 1]
>>> list1.sort()
>>> list1
[1, 9, 16, 25, 36]

字典介紹

字典是 Python 的內建資料類型之一,它定義了鍵和值之間一對一的關係。

  • Python 中的字典像 Perl 中的 hash (哈希陣列)。
  • Python 中的字典像 Java 中的 Hashtable 類的實例。
  • Python 中的字典像 Visual Basic 中的 Scripting.Dictionary 物件的實例。
  • 每一個元素都是一個鍵和值對 (key-value pair),整個元素集合用大括號括起來。
  • 可以通過來引用其值,使用方括號,但是不能通過值獲取鍵。
  • 字典的鍵是大小寫敏感
>>> # 字典有三種賦值方法蓊
>>> dic = {"program":"Python", "database":"mysql"}
>>> dic = dict(program = "Python", database = "mysql")
>>> dic = dict([("program","Python"), ("database","mysql")])
>>> dic
{'program': 'Python', 'database': 'mysql'}
>>> dic["program"]
'Python'
>>> dic["Python"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'Python'   
>>> dic["Program"] = "Java"
>>> dic
{'program': 'Python', 'database': 'mysql', 'Program': 'Java'}

字典的常用操作

  • copy():拷貝資料(淺拷貝)。
  • keys():取得所有鍵。
  • values():取得所有值。
  • items():取得所有元素。
  • clear():清空字典內元素。
  • del()內建函數:可以刪除特定元素或整個字典。
>>> dic = {"program":"Python", "database":"mysql"}
>>> dic2 = dic.copy()
>>> print(id(dic),id(dic2))
2079473853760 2079468906240
>>> dic.keys()
dict_keys(['program', 'database'])
>>> dic.values()
dict_values(['Python', 'mysql'])
>>> dic.items()
dict_items([('program', 'Python'), ('database', 'mysql')])
>>> del(dic["program"])
>>> dic
{'database': 'mysql'}
>>> dic.clear()
>>> dic
{}

元組介紹

  • 元組是不可變的列表。一旦創建了一個元組,就不能以任何方式改變它。
  • 定義元組與定義列表的方式相同,但整個元素集是用小括號包圍的,而不是方括號。
  • 元組的元素與列表一樣按定義的次序進行排序。元組的索引與列表一樣從 0 開始,所以一個非空元組的第一個元素總是 t[0]。
  • 負數索引與列表一樣從元組的尾部開始計數。
  • 與列表一樣分片 (slice) 也可以使用,當分割一個元組時,會得到一個新的元組。
  • 元組可以轉換成列表,反之亦然。
  • 元組沒有方法可以操作。
>>> t = (1, "mysql", "Python")
>>> t
(1, 'mysql', 'Python')
>>> t[0]
1
>>> t[-1]
'Python'
>>> t[1:3]
('mysql', 'Python')

使用元組有什麼好處

  • 元組比列表操作速度快。如果您定義了一個值的常量集,並且唯一要用它做的是不斷地遍歷它,請使用元組代替列表。
  • 如果對不需要修改的資料進行 「寫保護」,可以使代碼更安全,說明這一資料是常量。
  • 字典的鍵可以是字符串,整數、字串符或是元組。元組可以在字典中被用做鍵,但是列表不行。
  • 元組可以用在字符串格式化中。

集合介紹

Python 包含有集合類型。集合是由不重複元素組成的無序集合。它的基本用法包括成員檢測和消除重複元素。集合物件也支持像聯合,交集,差集,對稱差集等數學運算。大括號或 set() 函數可以用來創建集合。注意:要創建一個空集合你只能用 set() 而不能用 {},因為後者是創建一個空字典。

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # 消除重複元素 'orange', 'apple'
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # 判斷元素內容
True
>>> 'crabgrass' in basket
False
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # 不重複元素組成
{'a', 'r', 'b', 'c', 'd'}
>>> b
{'c', 'm', 'z', 'l', 'a'}
>>> a - b                              # a, b 差集
{'r', 'd', 'b'}
>>> a | b                              # a, b 聯合
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # a, b 交集
{'a', 'c'}
>>> a ^ b                              # a, b 對稱差集,只在 a 集合或是 b 集合的字元
{'r', 'd', 'b', 'm', 'z', 'l'}
  

上一篇
D03-Python 基礎語法
系列文
在AWS上進行物聯網與人工智慧實作4
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言